#include <stdlib.h>
#include "fatal.h"
#include "Stack.h"

#define EmptyTOS (-1)
#define MinStackSize (5)

struct StackRecord
{
    int Capacity;
    int TopOfStack;
    ElementType *Array;
};

Stack CreateStack( int MaxElements )
{
    Stack S;
    
    if (MaxElements < MinStackSize)
    {
        Error("Stack size is too small");
    }

    S = malloc(sizeof(struct StackRecord));

    if (S == NULL)
    {
        FatalError("Out of space !!");
    }

    S->Array = malloc(sizeof(ElementType)*MaxElements);
    if (S->Array == NULL)
    {
        FatalError("Out of space !!");
    }
    S->Capacity = MaxElements;
    MakeEmpty( S );
    return S;
}

void MakeEmpty( Stack S )
{
    S->TopOfStack = EmptyTOS;
}

void DisposeStack( Stack S )
{
    if (S != NULL)
    {
        free(S->Array);
        free(S);
    }
}

int IsEmpty( Stack S )
{
    return S->TopOfStack == EmptyTOS;
}

int IsFull( Stack S )
{
    return S->TopOfStack == S->Capacity-1;
}

void Push( ElementType X, Stack S )
{
    if (IsFull(S))
    {
        Error("Full Stack");
    }
    else
    {
        // 将 top of stack 自增
        S->Array[ ++S->TopOfStack ] = X;
    }
}

ElementType Top( Stack S )
{
    if (!IsEmpty(S))
    {
        return S->Array[S->TopOfStack];
    }
    else
    {
        Error("Empty Stack");
        return 0;
    }
}

void Pop( Stack S )
{
    if ( IsEmpty(S) )
    {
        Error("Empty Stack");
    }
    else
    {
        S->TopOfStack--;
    }
}

ElementType TopAndPop( Stack S )
{
    if (!IsEmpty(S))
    {
        return S->Array[S->TopOfStack--];
    }
    else
    {
        Error("Empty Stack");
        return 0;
    }
}